#pragma once
using namespace std;
#include <vector>
#include <queue>
#include "Mutex.hpp"
#include "Thread.hpp"
#include "Cond.hpp"
const int default_thread_num = 6;

template <typename T>
class ThreadPool
{
public:
    ThreadPool(int num = default_thread_num)
        : _num(num)
        
    {
        for (int i = 0; i < _num; i++)
        {
            _threads.emplace_back(
                [this]()
                {
                    HandlerTask();
                });
        }
    }
    void Start()
    {
        for (auto &thread : _threads)
        {
            thread.Start();
        }
    }
    void HandlerTask()
    {
        char name[128];
        pthread_getname_np(pthread_self(), name, sizeof(name));
        while (true)
        {
            T t;
            {
                MutexGuard mutexguard(_mutex);
                while (_task_q.empty())
                {
                    _cond.Wait(_mutex);
                }

                t = _task_q.front();
                _task_q.pop();
            }
            t();
        }
    }
    ~ThreadPool()
    {
    }

private:
    vector<Thread> _threads;
    queue<T> _task_q;
    int _num;
    Cond _cond;
    Mutex _mutex;
};